package pers.tetris;

import com.google.gson.Gson;
import pers.tetris.tools.ResourceList;

import java.nio.file.Files;

import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 形状的生成器
 */
public class ShapeMaker{
    /**
     * Shape配置文件的扫描规则，匹配  shapes/XXX.json 的文件
     */
    static final Pattern SHAPES_PATTERN = Pattern.compile(".*shapes[\\\\/].*\\.json");
    /**
     * 从文件加载的Shape列表
     */
    private List<Shape> shapeList = new ArrayList<>();
    /**
     * 形状队列,为保证每种形状出现概率相同，每次生成shapeList.size()个形状各一个，只是顺序不同
     */
    private Queue<Shape> queue = new LinkedList<>();

    private ShapeMaker() {
        Gson gson = new Gson();
        // 找到所有配置文件的路径
        List<String> shapePaths = ResourceList.getResources(SHAPES_PATTERN);
        for (String shapePath : shapePaths) {
            try {
                // 读取配置文件信息
                String text = Files.lines(Paths.get(shapePath))
                        .collect(Collectors.joining("\n"));
                // 转为FixedShape 对象
                FixedShape shape = gson.fromJson(text, FixedShape.class);
                shapeList.add(shape);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    // 单例模式
    static ShapeMaker shapeMaker;

    public static ShapeMaker getInstance()  {
        if (shapeMaker==null){
            shapeMaker = new ShapeMaker();
        }
        return shapeMaker;
    }

    /**
     * 产出下一个Shape
     * @return 新Shape
     */
    public Shape nextShape(){
        if (queue.isEmpty()){
            // 0..shapeList.size() 的数组
            List<Integer> indexes = IntStream.range(0,shapeList.size()).boxed().collect(Collectors.toList());
            // shuffle 打乱顺序
            Collections.shuffle(indexes);
            for (Integer index : indexes) {
                queue.add(shapeList.get(index));
            }
        }
        return queue.poll().clone();
    }
    public List<Shape> getShapeList() {
        return shapeList;
    }
}
